package com.haierp.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.framework.service.impl.SuperServiceImpl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.haierp.enums.StockUpStatus;
import com.haierp.exception.InventoryException;
import com.haierp.mapper.ErpOrderMapper;
import com.haierp.mapper.InventoryMapper;
import com.haierp.mapper.OuterOrderDetailMapper;
import com.haierp.mapper.OuterOrderMapper;
import com.haierp.model.ErpOrder;
import com.haierp.model.Inventory;
import com.haierp.model.Item;
import com.haierp.model.ItemSku;
import com.haierp.model.sale.OuterOrder;
import com.haierp.model.sale.OuterOrderDetail;
import com.haierp.service.IErpOrderService;
import com.haierp.service.IInventoryService;
import com.haierp.service.IItemService;
import com.haierp.service.IItemSkuService;
import com.haierp.service.IOuterOrderService;
import com.haierp.service.impl.InventoryServiceImpl.WarehouseCollector;
import com.haierp.util.JsonPageResult;
import com.haierp.vo.OuterOrderQueryVO;

@Service
public class OuterOrderServiceImpl extends SuperServiceImpl<OuterOrderMapper, OuterOrder>
		implements IOuterOrderService {

	@Autowired
	private OuterOrderMapper outerOrderMapper;
	@Autowired
	private OuterOrderDetailMapper outerOrderDetailMapper;
	@Autowired
	IErpOrderService erpOrderService;
	@Autowired
	private IItemSkuService itemSkuService;
	@Autowired
	private IItemService itemService;
	@Autowired
	private IInventoryService inventoryService;
	@Autowired
	private InventoryMapper inventoryMapper;
	@Autowired
	private ErpOrderMapper erpOrderMapper;

	@Override
	public void addOuterOrder(OuterOrder outerOrder) {
		outerOrderMapper.insertSelective(outerOrder);
		if (outerOrder.getOuterOrderDetails() != null && !outerOrder.getOuterOrderDetails().isEmpty()) {
			List<OuterOrderDetail> outerOrderDetails = outerOrder.getOuterOrderDetails();
			outerOrderDetails.forEach(outerOrderDetail -> {
				outerOrderDetail.setOuterOrderId(outerOrder.getId());
				outerOrderDetail.setGmtCreate(new Date());
				outerOrderDetail.setGmtModify(new Date());
				// 计算运费和销售价格
				ItemSku sku = itemSkuService.selectById(outerOrderDetail.getSkuId());
				if (sku != null) {
					outerOrderDetail.setColor(sku.getColor());
					outerOrderDetail.setItemName(sku.getItemName());
					outerOrderDetail.setScale(sku.getScale());
					outerOrderDetail.setSkuCode(sku.getSkuCode());
					outerOrderDetail.setThirdSkuCode(sku.getThirdSkuCode());
					outerOrderDetail.setUpc(sku.getUpc());
					outerOrderDetail.setItemId(sku.getItemId());
					outerOrderDetail.setCompanyId(sku.getCompanyId());//订单明细所属公司
					outerOrderDetail.setSkuPic(sku.getSkuPic());
					outerOrderDetail.setLogisticType(sku.getLogisticType());
					outerOrderDetail.setWeight(sku.getWeight());
					
					//如果有虚拟库存就扣减虚拟库存
					Inventory inventory = inventoryService.queryInventoryBySkuId(sku.getItemId(), sku.getId());
					if(inventory.getVirtualInv()>0 || inventory.getLockedVirtualInv()>0) {
						int virtualInv = inventory.getVirtualInv() - outerOrderDetail.getQuantity();
						virtualInv = virtualInv>0 ? virtualInv : 0;
						//如果虚拟库存小于等于可售库存，虚拟库存清零
						virtualInv = virtualInv>inventory.getTotalAvailableInv() ? virtualInv : 0;
						
						//如果虚拟占用库存大于零
						if(inventory.getLockedVirtualInv() > 0) {
							int lockedVirtualInv = inventory.getLockedVirtualInv() - outerOrderDetail.getQuantity();
							lockedVirtualInv = lockedVirtualInv>0 ? lockedVirtualInv : 0;
							inventory.setLockedVirtualInv(lockedVirtualInv);
						}
						inventory.setVirtualInv(virtualInv);
						inventory.setGmtModify(new Date());
						inventoryService.updateSelectiveById(inventory);
					}
				}
			});

			outerOrderDetailMapper.insertBatch(outerOrderDetails);
		}
	}

	@Override
	public OuterOrder queryOuterOrder(Long outerOrderId) {

		if (outerOrderId == null) {
			throw new RuntimeException("the outerOrder id is null");
		}
		OuterOrder outerOrder = outerOrderMapper.selectById(outerOrderId);

		if (outerOrder != null) {
			List<OuterOrderDetail> outerOrderDetails = outerOrderDetailMapper.selectOuterOrderDetailByOuterOrderId(outerOrderId);
			if (outerOrderDetails != null) {
				outerOrder.setOuterOrderDetails(outerOrderDetails);
			}
		}
		return outerOrder;
	}

	@Override
	public JsonPageResult<List<OuterOrder>> queryOuterOrderList(OuterOrderQueryVO outerOrderQueryVO) {
		JsonPageResult<List<OuterOrder>> outerOrderResult = new JsonPageResult<>();
		// 1、查询总的记录数量
		Integer totalCount = outerOrderMapper.queryOuterOrdersCount(outerOrderQueryVO);
		// 2、查询分页记录
		if (totalCount != null && totalCount != 0L) {
			outerOrderResult.buildPage(totalCount, outerOrderQueryVO);
			List<OuterOrder> outerOrders = outerOrderMapper.queryOuterOrders(outerOrderQueryVO);
			outerOrderResult.setData(outerOrders);
		} else {
			List<OuterOrder> outerOrders = new ArrayList<>();
			outerOrderResult.setData(outerOrders);
		}
		return outerOrderResult;
	}

	@Override
	public boolean updateOuterOrder(OuterOrder outerOrder) {
		outerOrderMapper.updateSelectiveById(outerOrder);
		List<OuterOrderDetail> outerOrderDetailList = outerOrder.getOuterOrderDetails();
		List<OuterOrderDetail> outerOrderDetailListNew = new ArrayList<>();
		List<OuterOrderDetail> outerOrderDetailListtUpdate = new ArrayList<>();
		// 获取数据库里面的所有sku
		OuterOrder outerOrderDb = queryOuterOrder(outerOrder.getId());
		List<OuterOrderDetail> outerOrderDetailListDb = outerOrderDb.getOuterOrderDetails();
		Set<Long> allDetails = new HashSet<Long>();
		Map<Long,OuterOrderDetail> detailMap = Maps.newHashMap();
		if (outerOrderDetailListDb != null && !outerOrderDetailListDb.isEmpty()) {
			outerOrderDetailListDb.forEach(detail -> {
				allDetails.add(detail.getId());
				detailMap.put(detail.getId(), detail);
			});
		}
		outerOrderDetailList.forEach(detail -> {
			if (detail.getId() == null) {
				detail.setOuterOrderId(outerOrder.getId());
				detail.setGmtCreate(new Date());
				detail.setGmtModify(new Date());
				outerOrderDetailListNew.add(detail);
			} else {
				if (!allDetails.isEmpty()) {
					allDetails.remove(detail.getId());
				}
				detail.setGmtModify(new Date());
				outerOrderDetailListtUpdate.add(detail);
			}

			ItemSku sku = itemSkuService.selectById(detail.getSkuId());
			if (sku != null) {
				detail.setColor(sku.getColor());
				detail.setUpc(sku.getUpc());
				detail.setItemName(sku.getItemName());
				detail.setScale(sku.getScale());
				detail.setSkuCode(sku.getSkuCode());
				detail.setThirdSkuCode(sku.getThirdSkuCode());
				detail.setItemId(sku.getItemId());
				detail.setCompanyId(sku.getCompanyId());
				detail.setSkuPic(sku.getSkuPic());
				detail.setLogisticType(sku.getLogisticType());
				Item item = itemService.selectById(sku.getItemId());
				if(item!=null && item.getFreight()!=null) {
					detail.setFreight(item.getFreight());
				}
			}
		});
		if (!outerOrderDetailListtUpdate.isEmpty()) {
			outerOrderDetailMapper.updateBatchById(outerOrderDetailListtUpdate);
		}
		if (!outerOrderDetailListNew.isEmpty()) {
			outerOrderDetailListNew.forEach(detail-> {
				detail.setCompanyId(outerOrder.getCompanyId());
			});
			outerOrderDetailMapper.insertBatch(outerOrderDetailListNew);
		}
		if (!allDetails.isEmpty()) {
			outerOrderDetailMapper.deleteBatchIds(new ArrayList<Long>(allDetails));
		}
		
		//更新ERP订单的判断1、没有新增订单 2、老订单的商品数量和SKU一致 3、可以有删除的订单
		boolean createErpOrder = true;
		if(outerOrderDetailListNew.isEmpty()){
			if (!outerOrderDetailListtUpdate.isEmpty()) {
				boolean allEquals = true;//更新的子订单全部相等
				for(OuterOrderDetail outerOrderDetail:outerOrderDetailListtUpdate){
					OuterOrderDetail outerOrderDetailDb = detailMap.get(outerOrderDetail.getId());
					if(outerOrderDetailDb!=null){
						if(!outerOrderDetailDb.getSkuId().equals(outerOrderDetail.getSkuId())||!outerOrderDetailDb.getQuantity().equals(outerOrderDetail.getQuantity())){
							allEquals = false;
							break;
						}
					}
				}
				createErpOrder = !allEquals;
				//更新每个ERPORDER 订单状态
				if(allEquals){
					for(OuterOrderDetail outerOrderDetail:outerOrderDetailListtUpdate){
						ErpOrder selectOrder = new ErpOrder();
						selectOrder.setOuterDetailOrderId(outerOrderDetail.getId());
						ErpOrder erpOrderDb = erpOrderService.selectOne(selectOrder);
						if(erpOrderDb!=null){
							erpOrderDb.setReceiver(outerOrder.getReceiver());
							erpOrderDb.setAddressDetail(outerOrder.getAddressDetail());
							erpOrderDb.setReceiverCity(outerOrder.getReceiverCity());
							erpOrderDb.setReceiverDistrict(outerOrder.getReceiverDistrict());
							erpOrderDb.setReceiverState(outerOrder.getReceiverState());
							erpOrderDb.setIdCard(outerOrder.getIdCard());
							erpOrderDb.setTelephone(outerOrder.getTelephone());
							erpOrderDb.setPostcode(outerOrder.getPostcode());
							erpOrderDb.setRemark(outerOrder.getRemark());
							erpOrderDb.setSalesId(outerOrder.getSalesId());
							erpOrderDb.setSalesName(outerOrder.getSalesName());
							erpOrderDb.setUserModify(outerOrder.getUserModify());
							erpOrderDb.setOrderTime(outerOrder.getOrderTime());
							erpOrderDb.setSalePrice(outerOrderDetail.getSalePrice());
							erpOrderService.updateById(erpOrderDb);
						}
						
					}
					if(!allDetails.isEmpty()){//释放删除订单的库存,并删除子订单
						for(Long orderId:allDetails){
							ErpOrder selectOrder = new ErpOrder();
							selectOrder.setOuterDetailOrderId(orderId);
							ErpOrder erpOrderDb = erpOrderService.selectOne(selectOrder);
							if(erpOrderDb!=null&&erpOrderDb.getStockStatus()!=StockUpStatus.INIT.getCode()&&erpOrderDb.getStockStatus()!=StockUpStatus.RELEASED.getCode()){
								try {
									inventoryService.releaseInventory(erpOrderDb);
								} catch (InventoryException e) {
									logger.info("释放库存异常,erpOrderId:"+erpOrderDb.getId());
									e.printStackTrace();
								}
							}
							erpOrderService.deleteById(erpOrderDb.getId());
						}
					}
				}
				
			}
		}
		return createErpOrder;
	}

	@Override
	public void deleteOuterOrder(OuterOrder outerOrder) {
		//删除主订单
		outerOrderMapper.deleteById(outerOrder.getId());
		Map<String, Object> columnMap = new HashMap<>();
		//删除主订单明细
		columnMap.put("outer_order_id", outerOrder.getId());
		outerOrderDetailMapper.deleteByMap(columnMap);
		//删除子订单
		erpOrderService.deleteByMap(columnMap);
	}

	/** 
	 * 方法中两部分别开启两个新事务处理
	 */
	@Override
	public void review(Long orderId,String addType) {
		// 1、审核导入
		erpOrderService.reviewOuterOrder(orderId,addType);
		// 2、锁定库存
		Map<String, Object> clumnMap = new HashMap<>();
		clumnMap.put("outer_order_id", orderId);
		List<ErpOrder> erpOrders = erpOrderService.selectByMap(clumnMap);
		if (CollectionUtils.isNotEmpty(erpOrders)) {
			try {
				//同一个仓库分配库存
				List<WarehouseCollector> wcs = inventoryService.selectWarehousesByErpOrders(erpOrders);
				Set<Long> erpOrderIds = Sets.newHashSet(); 
				if (CollectionUtils.isNotEmpty(wcs)) {
					for (WarehouseCollector wc : wcs) {
						try {
							erpOrderIds.add(wc.getErpOrderId());
							inventoryService.lockedInventroy(wc);
						} catch (InventoryException e) {
							this.logger.info(e.getMessage() + e);
							e.printStackTrace();
						} catch (Exception e) {
							this.logger.info(e.getMessage() + e);
							e.printStackTrace();
						}
					}
				}
				//落单的商品，其他的仓库随机分配库存
				erpOrders.forEach(erpOrder->{
					if(!erpOrderIds.contains(erpOrder.getId())){
						try {
							erpOrderService.lockErpOrder(erpOrder);
						} catch (InventoryException e) {
							this.logger.info(e.getMessage() + e);
							e.printStackTrace();
						} catch (Exception e) {
							this.logger.info(e.getMessage() + e);
							e.printStackTrace();
						}
					}
					//有赞推单/手动建单  （部分备货自动拆单）
					Long itemId = erpOrder.getItemId();
					Long skuId = erpOrder.getSkuId();
					Inventory inventory = inventoryMapper.getInventoryBySkuId(itemId, skuId);
					int totalAvailableInv = inventory.getTotalAvailableInv();
					if(erpOrder.getStockStatus()== StockUpStatus.PART.getCode() && totalAvailableInv > 0) {
						try {
							erpOrder.setIfSpiltAction(true);
							erpOrderService.splitErpOrder(erpOrder, erpOrder.getUnstockCount());
						} catch (InventoryException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});
			} catch (InventoryException e) {
				this.logger.info(e.getMessage() + e);
				e.printStackTrace();
			} catch (Exception e) {
				this.logger.info(e.getMessage() + e);
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public List<OuterOrder> queryOuterOrderForExcel(OuterOrderQueryVO outerOrderQueryVO) {
		return outerOrderMapper.queryOuterOrderForExcel(outerOrderQueryVO);
	}
}
